package com.tanker.base.plugin;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.List;

/**
 *
 * @author xiezm
 *
 */
public class MySqlPaginationPlugin extends PluginAdapter {

	// private static final String PAGE_CLASS_NAME = Page.class.getName();
	/**
	 * maper.xml里的MySql 分页前部分声明命名
	 */
	private static final String MySql_PAGINATION_PREFIX = "MySqlPaginationPrefix";

	/**
	 * maper.xml里的MySql 分页后部分声明命名
	 */
	private static final String MySql_PAGINATION_SUFFIX = "MySqlPaginationSuffix";

	@Override
	public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		// add field, getter, setter for limit clause
		// addPage(topLevelClass, introspectedTable, "page");
		return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
	}

	@Override
	public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
		XmlElement parentElement = document.getRootElement();
		// 产生分页语句后半部分
		XmlElement paginationSuffixElement = new XmlElement("sql");
		paginationSuffixElement.addAttribute(new Attribute("id", MySql_PAGINATION_SUFFIX));
		XmlElement pageEnd = new XmlElement("if");
		pageEnd.addAttribute(new Attribute("test", "page != null"));
        pageEnd.addElement(new TextElement("limit #{pageUtil.startRow} , #{pageUtil.pageSize}"));

		paginationSuffixElement.addElement(pageEnd);
		parentElement.addElement(paginationSuffixElement);
		return super.sqlMapDocumentGenerated(document, introspectedTable);
	}


    @Override
    public boolean sqlMapCountByExampleElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        String tableName = introspectedTable.getTableConfiguration().getTableName();
        /*StringBuilder builder = new StringBuilder();
        builder.append("<if test=\"isMaster\">\n");
        XmlElement masterElement = new XmlElement("if");
        masterElement.addAttribute(new Attribute("test","isMaster"));
        masterElement.addElement(new TextElement("*//* master *//*"));*/


        TextElement mainCountSelect = new TextElement("SELECT COUNT(1) FROM");

        XmlElement distinctFrom = new XmlElement("if");
        distinctFrom.addAttribute(new Attribute("test","distinct"));
        distinctFrom.addElement(new TextElement("(SELECT\n" +
                "          DISTINCT\n" +
                "          <include refid=\"Base_Column_List\"/>\n" +
                "          from "+tableName+"\n" +
                "          <if test=\"_parameter != null\">\n" +
                "              <include refid=\"Example_Where_Clause\"/>\n" +
                "          </if>) AS COUNT_SQL"));

        XmlElement noDistinctFrom = new XmlElement("if");
        noDistinctFrom.addAttribute(new Attribute("test","!distinct"));
        noDistinctFrom.addElement(new TextElement("\n" +
                "          "+tableName+"\n" +
                "          <if test=\"_parameter != null\" >\n" +
                "              <include refid=\"Example_Where_Clause\" />\n" +
                "          </if>\n"));

        element.getElements().clear();

        //element.addElement(masterElement);
        element.addElement(mainCountSelect);
        element.addElement(distinctFrom);
        element.addElement(noDistinctFrom);
        return true;
    }

    @Override
	public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
			IntrospectedTable introspectedTable) {
		XmlElement isNotNullElement = new XmlElement("include"); //$NON-NLS-1$
		isNotNullElement.addAttribute(new Attribute("refid", MySql_PAGINATION_SUFFIX));
		element.getElements().add(isNotNullElement);
		return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
	}

	/**
	 * This plugin is always valid - no properties are required
	 */
	public boolean validate(List<String> warnings) {
		return true;
	}
}